package dai.samples.jpa.service;

import dai.samples.jpa.bean.UserCartInfo;
import dai.samples.jpa.entity.User;
import dai.samples.jpa.repository.UserRepository;
import dai.samples.jpa.repository.UserRoleRepository;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.List;

/**
 *
 * @author daify
 * @date 2019-07-31
 **/
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserRoleRepository userRoleRepository;

    @PersistenceContext
    @Autowired
    private EntityManager entityManager;
    
    public User getUserWithNativeQuery(Long id) {
        String sql = "select * from cascade_user where id = ?";
        Query nativeQuery = entityManager.createNativeQuery(sql, User.class);
        nativeQuery.setParameter(1,id);
        List<User> resultList = nativeQuery.getResultList();
        User o = resultList.get(0);
        return o;
    }

    public UserCartInfo getUserInfoWithNativeQuery(Long id) {
        String sql = "select u.*,c.id as 'cartId',"
                     + "c.count,c.total_money as 'totalMoney',c.update_time as 'updateTime'"
                     + "from cascade_user u "
                     + "left join cascade_user_cart c "
                     + "on c.user_id = u.id "
                     + "where u.id = ?";
        Query query = entityManager.createNativeQuery(sql);
        query.setParameter(1,id);
        // @todo develop a new approach to result transformers
        // For 6.0 we will move those methods here and then delete that class.
        query.unwrap(NativeQuery.class).setResultTransformer(Transformers.aliasToBean(UserCartInfo.class));
        List resultList = query.getResultList();
        return (UserCartInfo) resultList.get(0);
    }

    public User getUserWithQuery(Long id) {
        String sql = "select u FROM User u where u.id = :id";
        TypedQuery <User> query = entityManager.createQuery(sql, User.class);
        query.setParameter("id",id);
        return query.getSingleResult();
    }

    public User getUserWithBuilder(User user) {

        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery <User> query = builder.createQuery(User.class);
        Root <User> from = query.from(User.class);
        Path <Object> id = from.get("id");
        builder.equal(id,user.getId());
        Path <Object> name = from.get("name");
        builder.equal(name,user.getName());
        Path <Object> age = from.get("age");
        builder.equal(age,user.getAge());
        TypedQuery <User> rest = entityManager.createQuery(query);
        User result = rest.getSingleResult();
        return result;
    }

}
